1 module hip.filesystem.systems.cstd;
2 import hip.api.filesystem.hipfs;
3 
4 
5 /**
6 *   All those string allocations should be removed or turnt into @nogc somehow. The better cached, the best.
7 *
8 */
9 class HipCStdioFileSystemInteraction : IHipFileSystemInteraction
10 {
11     version(Windows)
12         pragma(lib, "Shlwapi.lib"); //PathIsDirectory
13     bool read(string path, FileReadResult delegate(ubyte[] data) onSuccess, void delegate(string err) onError)
14     {
15         import core.stdc.stdio;
16         import hip.error.handler;
17         import hip.util.conv;
18         if(ErrorHandler.assertLazyErrorMessage(exists(path), "FileSystem Error:", "Filed named '"~path~"' does not exists"))
19             return false;
20 
21         auto f = fopen((path~"\0").ptr, "rb");
22         if(f is null)
23         {
24             onError("File not found.");
25             return false;
26         }
27         if(fseek(f, 0, SEEK_END))
28         {
29             fclose(f);
30             onError("Could not seek to file end.");
31             return false;
32         }
33         auto size = ftell(f);
34 
35         if(size <= 0)
36         {
37             fclose(f);
38             onError("Size <= 0 on file "~path);
39             return false;
40         }
41         if(fseek(f, 0, SEEK_SET))
42         {
43             fclose(f);
44             onError("Could not seek to file beginning");
45             return false;
46         }
47         import hip.util.array;
48         ubyte[] output = uninitializedArray!(ubyte[])(size);
49 
50         if(size_t readed = fread(cast(void*)output.ptr, 1, cast(size_t)size, f) != size)
51         {
52             fclose(f);
53             onError("File is corrupted. Could not read file entirely (Readed "~to!string(readed)~") Expected "~to!string(size));
54             return false;
55         }
56         fclose(f);
57         onSuccess(output);
58         return true;
59     }
60     bool write(string path, const(void)[] data)
61     {
62         import core.stdc.stdio;
63         if(exists(path))
64         {
65             auto file = fopen(cachedStringz(path), "w");
66             scope(exit)
67                 fclose(file);
68             if(fwrite(data.ptr, 1, data.length, file) != data.length)
69             {
70                 return fflush(file) == 0;
71             }
72             return true;
73         }
74         return false;
75     }
76     bool exists(string path)
77     {
78         import core.stdc.stdio;
79         if(auto file = fopen(cachedStringz(path), "r"))
80         {
81             fclose(file);
82             return true;
83         }
84         return false;
85     }
86     bool remove(string path)
87     {
88         static import core.stdc.stdio;
89         if(exists(path))
90         {
91             return core.stdc.stdio.remove(cachedStringz(path)) == 0;
92         }
93 
94         return false;
95     }
96 
97     version(Windows)
98     {
99         private alias BOOL = int;
100         private alias LPCSTR = const(char)*;
101         extern(Windows) BOOL PathIsDirectoryA(LPCSTR);
102     }
103 
104     bool isDir(string path)
105     {
106         version(Windows)
107         {
108             return PathIsDirectoryA(cachedStringz(path)) == 1;
109         }
110         else version(Posix)
111         {
112             import core.sys.posix.sys.stat;
113             stat_t st;
114             stat(cachedStringz(path), &st);
115             return S_ISDIR(st.st_mode);
116         }
117         else return path[$-1] == '/';
118     }
119     
120 }